/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 simulated_combat_creature.h

	$Header: /heroes4/simulated_combat_creature.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SIMULATED_COMBAT_CREATURE_H_INCLUDED )
#define SIMULATED_COMBAT_CREATURE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_combat_creature.h"

class t_combat_creature;

// -----------------------------------------------------
// creature data for a simulated combat
// -----------------------------------------------------
class t_simulated_combat_creature : public t_counted_object, 
                                    public t_abstract_combat_creature
{
public:
	t_simulated_combat_creature( t_creature_stack* creature, int slot, bool defender,
								 double effectiveness, 
								 t_abstract_grail_data_source const& grail_data,
								 t_player const* owner );
	explicit t_simulated_combat_creature( t_combat_creature const& creature );

	void			add_wounds( int arg, int turn );
	bool			can_retaliate( t_simulated_combat_creature const& attacker ) const;
	bool			can_shoot() const;
	void		    cast_spell_on( t_spell spell, t_simulated_combat_creature& target );
	bool			casts_spells() const;
	void			do_melee( t_simulated_combat_creature& defender, int turn );
	void			do_ranged_attack( t_simulated_combat_creature& defender, int turn );
	int				get_damage( t_simulated_combat_creature const& defender ) const;
	double			get_effectiveness() const;
	int											get_first_casualty_time() const;
	virtual t_abstract_grail_data_source const& get_grail_data() const;
	int				get_lifespan() const;
	int				get_position() const;
	double			get_spell_defense() const;
	double			get_spell_offense() const;
	int				get_total_hits() const;
	void			process_new_turn();
	void			resurrect( int amount );
	void			set_defense( double amount );
	void			set_effectiveness( double effectiveness );
	void			set_first_casualty_time( int arg );
	void			set_lifespan( int arg );
	void			set_offense( double amount );
	void			set_position( int arg );
	virtual void	set_spell( t_spell spell, 
							   t_combat_action_message const & message,
							   int power = 0,
		                       t_spell_source = k_spell_source_spell );
	void			set_spell( t_spell spell,
							   int power = 0,
		                       t_spell_source = k_spell_source_spell );

protected:
	void do_attack( t_simulated_combat_creature&	defender,
					bool							attacker_has_first_strike,
					bool							defender_has_first_strike,
					int								attacks,
					int								turns );
	void heal( int amount );
	void set_enchantment( t_spell spell, int numerator, int denominator );

	double	m_defense;
	double	m_effectiveness;
	int		m_first_casualty_time;
	t_abstract_grail_data_source const& m_grail_data;
	int		m_lifespan;			// approximate measure of how long this stack lasted
	double	m_offense;
	double	m_position;
	double	m_spell_defense;
	double	m_spell_offense;
};

inline bool t_simulated_combat_creature::casts_spells() const
{
	return m_spell_points >= 10;
}

inline double t_simulated_combat_creature::get_effectiveness() const
{
	return m_effectiveness;
}

inline int t_simulated_combat_creature::get_first_casualty_time() const
{
	return m_first_casualty_time;
}

inline int t_simulated_combat_creature::get_lifespan() const
{
	return m_lifespan;
}

inline int t_simulated_combat_creature::get_position() const
{
	return m_position;
}

inline void t_simulated_combat_creature::set_defense( double amount )
{
	m_defense = amount;
}

inline void t_simulated_combat_creature::set_effectiveness( double effectiveness )
{
	m_effectiveness = effectiveness;
}

inline void t_simulated_combat_creature::set_first_casualty_time( int arg )
{
	m_first_casualty_time = arg;
}

inline void t_simulated_combat_creature::set_lifespan( int arg )
{
	m_lifespan = arg;
}

inline void t_simulated_combat_creature::set_offense( double amount )
{
	m_offense = amount;
}

inline void t_simulated_combat_creature::set_position( int arg )
{
	m_position = arg;
}

inline double t_simulated_combat_creature::get_spell_defense() const
{
	return m_spell_defense;
}

inline double t_simulated_combat_creature::get_spell_offense() const
{
	return m_spell_offense;
}

inline int t_simulated_combat_creature::get_total_hits() const
{
	return (m_number * get_hit_points()) - m_wounds;
}

#endif